Tegra: bpmp_ipc: support to enable/disable module clocks
authorsteven kao <[email protected]>
Wed, 3 Jan 2018 03:07:00 +0000 (19:07 -0800)
committerVarun Wadekar <[email protected]>
Thu, 31 Jan 2019 16:45:49 +0000 (08:45 -0800)
This patch adds support to the bpmp_ipc driver to allow clients to
enable/disable clocks to hardware blocks. Currently, the API only
supports SE devices.

Change-Id: I9a361e380c0bcda59f5a92ca51c86a46555b2e90
Signed-off-by: steven kao <[email protected]>
plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c
plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h
plat/nvidia/tegra/include/drivers/bpmp_ipc.h

index 7faa2f09e6d26ccf1a56e832b4b197b97a939700..2efa1bd984032836d588e5a2a4e5023fc12589a4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -302,3 +302,49 @@ int32_t tegra_bpmp_ipc_reset_module(uint32_t rst_id)
 
        return ret;
 }
+
+int tegra_bpmp_ipc_enable_clock(uint32_t clk_id)
+{
+       int ret;
+       struct mrq_clk_request req;
+
+       /* only SE clocks are supported */
+       if (clk_id != TEGRA_CLK_SE) {
+               return -ENOTSUP;
+       }
+
+       /* prepare the MRQ_CLK command */
+       req.cmd_and_id = make_mrq_clk_cmd(CMD_CLK_ENABLE, clk_id);
+
+       ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, sizeof(req),
+                       NULL, 0);
+       if (ret != 0) {
+               ERROR("%s: failed for module %d with error %d\n", __func__,
+                     clk_id, ret);
+       }
+
+       return ret;
+}
+
+int tegra_bpmp_ipc_disable_clock(uint32_t clk_id)
+{
+       int ret;
+       struct mrq_clk_request req;
+
+       /* only SE clocks are supported */
+       if (clk_id != TEGRA_CLK_SE) {
+               return -ENOTSUP;
+       }
+
+       /* prepare the MRQ_CLK command */
+       req.cmd_and_id = make_mrq_clk_cmd(CMD_CLK_DISABLE, clk_id);
+
+       ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, sizeof(req),
+                       NULL, 0);
+       if (ret != 0) {
+               ERROR("%s: failed for module %d with error %d\n", __func__,
+                     clk_id, ret);
+       }
+
+       return ret;
+}
index 689f8bbb82b33814438ef3b6a04da9493f25470d..7059c3701688001402e39199dee8a9e1b396b991 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
  * Flags used in IPC req
  */
 #define FLAG_DO_ACK                    (U(1) << 0)
-#define FLAG_RING_DOORBELL             (U(1) << 1)
+#define FLAG_RING_DOORBELL     (U(1) << 1)
 
 /* Bit 1 is designated for CCPlex in secure world */
-#define HSP_MASTER_CCPLEX_BIT          (U(1) << 1)
+#define HSP_MASTER_CCPLEX_BIT  (U(1) << 1)
 /* Bit 19 is designated for BPMP in non-secure world */
 #define HSP_MASTER_BPMP_BIT            (U(1) << 19)
 /* Timeout to receive response from BPMP is 1 sec */
@@ -49,9 +49,10 @@ struct frame_data {
  */
 
 /**
- * MRQ code to issue a module reset command to BPMP
+ * MRQ command codes
  */
 #define MRQ_RESET                      U(20)
+#define MRQ_CLK                                U(22)
 
 /**
  * Reset sub-commands
@@ -71,4 +72,56 @@ struct __attribute__((packed)) mrq_reset_request {
        uint32_t reset_id;
 };
 
+/**
+ * MRQ_CLK sub-commands
+ *
+ */
+enum {
+       CMD_CLK_GET_RATE = 1,
+       CMD_CLK_SET_RATE = 2,
+       CMD_CLK_ROUND_RATE = 3,
+       CMD_CLK_GET_PARENT = 4,
+       CMD_CLK_SET_PARENT = 5,
+       CMD_CLK_IS_ENABLED = 6,
+       CMD_CLK_ENABLE = 7,
+       CMD_CLK_DISABLE = 8,
+       CMD_CLK_GET_ALL_INFO = 14,
+       CMD_CLK_GET_MAX_CLK_ID = 15,
+       CMD_CLK_MAX,
+};
+
+/**
+ * Used by the sender of an #MRQ_CLK message to control clocks. The
+ * clk_request is split into several sub-commands. Some sub-commands
+ * require no additional data. Others have a sub-command specific
+ * payload
+ *
+ * |sub-command                 |payload                |
+ * |----------------------------|-----------------------|
+ * |CMD_CLK_GET_RATE            |-                      |
+ * |CMD_CLK_SET_RATE            |clk_set_rate           |
+ * |CMD_CLK_ROUND_RATE          |clk_round_rate         |
+ * |CMD_CLK_GET_PARENT          |-                      |
+ * |CMD_CLK_SET_PARENT          |clk_set_parent         |
+ * |CMD_CLK_IS_ENABLED          |-                      |
+ * |CMD_CLK_ENABLE              |-                      |
+ * |CMD_CLK_DISABLE             |-                      |
+ * |CMD_CLK_GET_ALL_INFO        |-                      |
+ * |CMD_CLK_GET_MAX_CLK_ID      |-                      |
+ *
+ */
+struct mrq_clk_request {
+       /**
+        * sub-command and clock id concatenated to 32-bit word.
+        * - bits[31..24] is the sub-cmd.
+        * - bits[23..0] is the clock id
+        */
+       uint32_t cmd_and_id;
+};
+
+/**
+ * Macro to prepare the MRQ_CLK sub-command
+ */
+#define make_mrq_clk_cmd(cmd, id)      (((cmd) << 24) | (id & 0xFFFFFF))
+
 #endif /* INTF_H */
index 9304150e943fde80e20217de97801c9e11839a97..d487956082b88989d49f65e7091c98972e2ec648 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #define TEGRA_RESET_ID_XUSB_PADCTL     U(114)
 #define TEGRA_RESET_ID_GPCDMA          U(70)
 
+/**
+ * Clock identifier for the SE device
+ */
+#define TEGRA_CLK_SE        U(124)
+
 /**
  * Function to initialise the IPC with the bpmp
  */
@@ -27,4 +32,16 @@ int32_t tegra_bpmp_ipc_init(void);
  */
 int32_t tegra_bpmp_ipc_reset_module(uint32_t rst_id);
 
+/**
+ * Handler to enable clock to a module. Only SE device is
+ * supported for now.
+ */
+int tegra_bpmp_ipc_enable_clock(uint32_t clk_id);
+
+/**
+ * Handler to disable clock to a module. Only SE device is
+ * supported for now.
+ */
+int tegra_bpmp_ipc_disable_clock(uint32_t clk_id);
+
 #endif /* __BPMP_IPC_H__ */